#include "Listener.h"
#include "BaseMsg.h"
#include <unistd.h> 


void Listener::MainFun(Listener* l)
{
    while(1)
    {
        char buf[1024];
        struct sockaddr_in client;
        int len = l->conn->recv(buf,1024,client);
        if(len < 8)
            continue;
        l->count++;
        l->Logic(buf,len,client);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
Listener::Listener(std::string ip,int port_)
    :addr(ip),port(port_)
{
}
Listener::~Listener()
{
}
std::shared_ptr<KcpConnect> Listener::accept()
{
    std::shared_ptr<KcpConnect> ret = nullptr;
    if(!acclist.empty())
    {
        auto acp = acclist.front();
        acclist.pop_front(); 
        ret = acp.conn;
    }
    return ret;
}

void Listener::NotifAll()
{
    if(count >= 1)
    {
        cv.notify_all();
        count=0;
    }
}

//TODO：后面需要重新整理流程
void Listener::Logic( char *buf, int len,struct sockaddr_in addrs )
{
    int code = UdpConnect::bytesToInt(buf);
    int id = UdpConnect::bytesToInt(buf+4);
    switch(code)
    {
        case BaseMsg::MSG_HEAD_TEPE_CONNECT:     //建立链接
            {
                id = beginSessid++;
                if(list.find(id) != list.end())
                    return;
                std::shared_ptr<UdpConnect> pcon = std::make_shared<UdpConnect>(addrs,this->conn->GetFd());
                list.emplace(id,pcon);
                Accept acp;
                acp.conn = std::make_shared<KcpConnect>(pcon,id);
                acp.conn->ConnectSuccess();
                acclist.push_back(acp);
                std::lock_guard<std::mutex> lk(lock);
                change.insert(0);       //如果是0则代表着新连接进入
            }
            break;
        case BaseMsg::MSG_HEAD_TEPE_CONTENT://数据 //TODO:只是暂时而已，后续改
            {
                if(len > 8)
                {
                    auto pcon = list.find(id);
                    if(pcon != list.end())
                    {
                        pcon->second->put(buf+8,len - 8);
                        std::lock_guard<std::mutex> lk(lock);
                        change.insert(id);
                    }
                }
            }
            break;
        case BaseMsg::MSG_HEAD_TEPE_CLOSE:
            {
                //TODO:关闭需要通知上层
            }
            break;
        default:
            break;
    }
    NotifAll();
}
void Listener::EpollWait(std::set<uint32_t>& v)
{
    {
       std::unique_lock<std::mutex> lk(lock);
         cv.wait(lk);
    }
    std::lock_guard<std::mutex> lk(lock);
     v = change;
     change.clear();
}
int Listener::bind()
{
    conn = std::unique_ptr<UdpConnect>(new UdpConnect(addr,port));
    int ret = conn->bind();
    //创建线程
    if(ret < 0)
        return ret;
    t1 = std::thread(Listener::MainFun,this);
    return ret;
}
